package JAVA300.第十一章多线程;

/**管程法实现生产者消费者问题
 * 1，先加锁 并发
 * 2.进行操作控制
 *
 */



public class thread_18_corp_monitor1 {
    public static void main(String[] args) {

        SynContainer container = new SynContainer();
        new Productor(container).start();
        new Consumer(container).start();

    }

}

//生产者

class Productor extends Thread{

    SynContainer container = new SynContainer();

    public Productor(SynContainer container) {
        this.container = container;
    }

    @Override
    public void run() {
        for (int i=0;i<5;i++){
            System.out.println("生产-->第"+i+"个面包");
            container.push(new Breads(i));

        }

    }
}

//消费者
class Consumer extends Thread{

    SynContainer container = new SynContainer();

    public Consumer(SynContainer container) {
        this.container = container;
    }
    @Override
    public void run() {
        for (int i=0;i<5;i++){
            System.out.println("消费-->第"+container.pop().id+"个面包");
            container.pop();

        }



    }
}
//缓冲区
class SynContainer{

    Breads[] breads = new Breads[10];//存储容器
    int count=0;


    //存储--生产

    public synchronized void push(Breads bread){

        if (count== breads.length){//缓存区满了

            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        breads[count] = bread;
        count++;//唤醒
        this.notifyAll();

    }
    //获取--消费者--默认从后取
    public synchronized Breads pop(){
        //有数据时才能pop
        if (count ==0){
            //没有数据 等待
            try {
                this.wait();//线程阻塞--生产者通知消费
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
        count--;
        Breads bread = breads[count];
        this.notifyAll();//唤醒
        return bread;






    }

}
//数据-面包

class Breads{
    int id;

    public Breads(int id) {
        this.id = id;
    }
}